package com.ts.api.module.match.plan.internal.qualification.strategy;

import com.gitee.apanlh.util.base.BigDecimalUtils;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.common.SwitchEnum;
import com.ts.api.common.context.ApiContext;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.entity.vo.ReqApiParameterVO;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualification;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualificationResult;
import com.ts.api.module.match.plan.model.ApiPlanMatch;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductPlanTypeService;
import com.ts.api.module.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *  API渠道-计划资质验证
 *
 *  @author Pan
 */
@Service
public class ApiChannelQualification implements PlanQualificationStrategy<ApiPlanMatch> {

    @Autowired
    private BaseQualification baseQualification;
    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private ProductPlanTypeService productPlanTypeService;
    @Autowired
    private ProductService productService;

    @Override
    public PlanQualification convert(ApiPlanMatch abstractPlanMatch) {
        //  获取渠道信息
        ApiKeyPO apiKeyPO = abstractPlanMatch.getApiKeyPO();
        Integer apiEnvType = apiKeyPO.getApiEnvType();
        String apiClientId = apiKeyPO.getApiClientId();
        Long loanChannelId = apiKeyPO.getLoanChannelId();

        //  获取用户表单+用户信息
        ReqApiParameterVO reqApiParameterVO = abstractPlanMatch.getReqApiParameterVO();
        ApiUserRequest apiUserRequest = reqApiParameterVO.getApiUserRequest();

        Long reqId = ClassConvertUtils.toLong(ApiContext.REQ_ID.get());
        String reqIdStr = String.valueOf(reqId);
        apiUserRequest.setReqId(reqIdStr);

        //  设置城市信息
        DistrictPO districtPO = DistrictCache.getByName(apiUserRequest.getCity());
        apiUserRequest.setAreaCode(districtPO.getCode());
        apiUserRequest.setCity(districtPO.getName());
        apiUserRequest.setProvinceName(districtPO.getProvinceName());
        apiUserRequest.setProvinceCode(districtPO.getProvinceCode());

        //  设置渠道信息
        apiUserRequest.setEnvType(apiEnvType);
        apiUserRequest.setApiClientId(apiClientId);
        apiUserRequest.setLoanChannelId(loanChannelId);

        //  转换资质实体
        PlanQualification planQualification = new PlanQualification();
        planQualification.setReqId(reqIdStr);
        planQualification.setApiUserRequest(apiUserRequest);
        planQualification.setListPlanType(abstractPlanMatch.getListPlanType());
        planQualification.setEnableFilterDistributeByUser(true);
        return planQualification;
    }

    @Override
    public PlanQualificationResult filter(PlanQualification planQualification, ApiPlanMatch apiPlanMatch) {
        ApiKeyPO apiKeyPO = apiPlanMatch.getApiKeyPO();
        ApiUserRequest apiUserRequest = planQualification.getApiUserRequest();

        //  1.验证城市是否为空
        DistrictPO districtPO = baseQualification.validArea(planQualification);
        if (ValidParam.isNull(districtPO)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_AREA_ERROR));
        }

        //  2.过滤计划类型
        List<ProductPlanPO> listPlan = baseQualification.filterPlanType(planQualification, apiPlanMatch);
        if (ValidParam.isEmpty(listPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_AREA_EMPTY));
        }

        //  3.验证当前时间符合计划时间
        List<ProductPlanPO> listPlanOpenTime = baseQualification.validOpenTime(listPlan);
        if (ValidParam.isEmpty(listPlanOpenTime)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_PLAN_TIME_EMPTY));
        }

        //  4.渠道匹配模式验证
        List<ProductPlanPO> listVersionPlan = CollUtils.find(listPlanOpenTime, productPlanPO -> {
            //  本地cmr计划忽略验证
            ProductPO productPO = productService.get(productPlanPO.getLoanProductId());
            if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
                return true;
            }

            //  API渠道版本验证
            boolean requiredApiChannelPlanVersion = apiBizRequiredService.requiredApiChannelPlanVersion(apiKeyPO, productPlanPO);
            //  API渠道模式验证
            boolean versionModeConsistency = apiBizRequiredService.requiredApiChannelPlanModeVersion(apiKeyPO, productPlanPO);
            return requiredApiChannelPlanVersion && versionModeConsistency;
        });
        if (ValidParam.isEmpty(listVersionPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  5.过滤用户资质与当前匹配计划资质不符合项
        List<ProductPlanPO> listQualificationPlan = baseQualification.filterUserField(listVersionPlan, apiUserRequest);
        if (ValidParam.isEmpty(listQualificationPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  6.过滤计划单价低于当前渠道
        BigDecimal apiPrice = apiKeyPO.getApiPrice();
        List<ProductPlanPO> listPricePlan = baseQualification.filterPrice(listQualificationPlan, apiPrice);
        if (ValidParam.isEmpty(listPricePlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  7.定制渠道-推送有关联 -> 筛选出“取消唤醒功能”或“价格大于0”的计划或"分润大于0"的计划
        List<ProductPlanPO> listFilterPlan = listPricePlan.stream()
            .filter(item -> Objects.equals(item.getEnableFilterLocal(), SwitchEnum.DISABLE.getType()) || BigDecimalUtils.compare(item.getPrice(), 0) > 0 || BigDecimalUtils.compare(item.getShare(), 0) > 0)
        .collect(Collectors.toList());

        //  8.如果最终无计划分发抛出异常
        if (ValidParam.isEmpty(listFilterPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_FAIL2));
        }

        //  9.返回验证通过实体
        PlanQualificationResult planQualificationResult = new PlanQualificationResult();
        planQualificationResult.setReqId(planQualification.getReqId());
        planQualificationResult.setApiUserRequest(apiUserRequest);
        planQualificationResult.setAbstractPlanMatch(apiPlanMatch);
        planQualificationResult.setListPlanQualification(listFilterPlan);
        return planQualificationResult;
    }
}
